package org.datascooter.bundle.attribute;

import java.lang.reflect.Field;

import org.datascooter.exception.DataScooterException;
import org.datascooter.utils.DBType;

/**
 * This persistable attribute may be restored into instance variable via field access
 * 
 * @author nemo
 * 
 */
public class PersistFieldAttribute extends PersistAttribute {

	protected Field field;

	public PersistFieldAttribute(String name, String column, DBType type, int scale, int precision, boolean insertable, boolean updatable, boolean nullable) {
		super(name, type, column, scale, precision, nullable, insertable, updatable);
	}

	@SuppressWarnings("unchecked")
	@Override
	public PersistFieldAttribute copy() {
		return new PersistFieldAttribute(name, getColumn(), getType(), getScale(), getPrecision(), insertable, updatable, isNullable());
	}

	@SuppressWarnings("unchecked")
	@Override
	public PersistFieldAttribute copyMod(DBType dbType) {
		return new PersistFieldAttribute(name, getColumn(), dbType, scale, precision, insertable, updatable, isNullable());
	}

	@Override
	public void explore(Class<?> clazz) {
		Class<?> clazz1 = clazz;
		while (field == null) {
			try {
				field = clazz1.getDeclaredField(name);
			} catch (Exception e) {
				clazz1 = clazz1.getSuperclass();
				if (clazz1 == null) {
					throw new DataScooterException("***No field found  " + e.getMessage());
				}
			}
		}
		field.setAccessible(true);
		setGetClass(field.getType());
		setSetClass(field.getType());
	}

	@Override
	public String getActorName() {
		return field.getName();
	}

	@Override
	protected Object invoke(Object obj) throws IllegalArgumentException, IllegalAccessException {
		return field.get(obj);
	}

	@Override
	protected void revoke(Object obj, Object param) throws IllegalArgumentException, IllegalAccessException {
		field.set(obj, param);
	}
}
